#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
-------------------------------------------------
   File Name:    assertion_handler.py
   Description:  断言处理模块
-------------------------------------------------
"""

import requests

from apitesting.src.models.test_suite.test_suite_model import TestSuite
from apitesting.common.db.mysql_handler import mysql_handler as ConnectMysql
# from apitesting.models.test_suite import Assertion
from apitesting.src.models import Assertion
from apitesting.common.util.logger import log
from apitesting.src.utils.asserts.response_json import ResponseJsonAssert
from apitesting.src.enums.assert_type import AssertIntType, AssertStrType
from apitesting.src.enums.response_target_obj import ResponseTargetObj


def response_assert(testcase: TestSuite):
    for data in zip(testcase.check, testcase.result):
        if "all_response" in data[0]:
            log.info("开始执行 all_response 接口全量返回值校验逻辑")
            # 后续版本更新
            pass


class ResponseAssert:
    """断言方法的前置"""

    @staticmethod
    def exec_asserter(assertion: Assertion, response: requests.models.Response):
        if assertion.target_obj == ResponseTargetObj.JSON:
            # log.info("开始执行 json 校验逻辑")
            return ResponseAssert()._json_asserter(assertion=assertion, response_json=response.json())
        else:
            log.error(f"暂不支持该对响应JSON断言方法")
            raise Exception('暂不支持该对响应JSON断言方法！')

    @staticmethod
    def _json_asserter(assertion: Assertion, response_json: dict) -> list:
        """
        json类型断言
        :param: assertion = 断言模型 Assertion(name='测试状态响应断言', target_object='Response JSON', jsonpath='$.code', key='equals', value='200')
        :param: response = 响应
        :return:
        """
        if not isinstance(response_json, dict):
            log.error(f"json 断言内容格式错误，响应不是 JSON 格式, 是{type(response_json)}:")
            raise Exception('响应不是 JSON 格式')

        # 获取断言结果数据
        assert_method = None
        try:
            # 判断是否在枚举中，拿到断言的方法（相等，不想等...）
            if assertion.key in AssertIntType.get_all_values():
                assert_method = AssertIntType.get_name_by_value(assertion.key)
            elif assertion.key == AssertStrType.get_all_values():
                assert_method = AssertStrType.get_name_by_value(assertion.key)
            else:
                log.error(f"不存在该对响应JSON断言方法:{assertion.key}")
                # assert_method = assertion.key
                # sys.exit()

            # log.debug(f"JSON断言,断言方法:{AssertIntType.get_name_by_value(assertion.key)}")
            # 获取断言方法
            # method = assertion.key.lower()

            # 判断是否存在断言方法
            assert_results_list = list()
            if assert_method:
                if hasattr(ResponseJsonAssert, assert_method):
                    # 调用断言方法
                    assert_result_str: str = getattr(ResponseJsonAssert(
                        response_json=response_json,
                        assert_data=assertion
                    ), assert_method)()
                    # 添加断言结果
                    assert_results_list.append(assert_result_str)
                else:
                    log.error(f"程序中不存在该响应断言方法:{assert_method}")
            else:
                log.error(f"枚举中不存在该响应断言方法: {assert_method}")

            # response_value = jsonpath.jsonpath(response_json, assertion.jsonpath)[0]
            # if response_value:
            #     log.info(f"执行 json 断言: {assertion.model_dump()}")
            #     assertion_results.append(
            #         self._exec_json_assert(assertion=assertion, actual_value=response_value)
            #     )
            # else:
            #     log.error(f"响应JSON断言失败,断言路径:{assertion.jsonpath}不存在")
            #     raise Exception('响应JSON断言失败,断言路径:{}'.format(assertion.jsonpath))
        except Exception as e:
            log.error(f"校验异常请检查,错误信息:{e}")
            raise Exception('校验异常请检查！')

        # 断言结果返回
        return assert_results_list

    @staticmethod
    def check_response_sql(data):
        """数据库操作"""
        log.info("------------------ 开始执行 sql 校验逻辑 ------------------")
        # 获取数据库连接
        mysql_name = data[0].get("sql")[0]
        sql = data[0].get("sql")[1]
        with ConnectMysql(mysql_name) as db:
            query_results = db.fetch_one(sql)
        log.info("开始比对 sql 的值和字段校验的值")
        for i in range(len(query_results)):
            if query_results[i] == data[1][i]:
                log.info(f"{query_results[i]} == {data[1][i]} ---校验通过")
            else:
                log.info(f"{query_results[i]} == {data[1][i]} ---校验失败(如果日志打印出来的结果一致请检查数据类型)")
                log.info(f"{query_results[i]} 类型为:{type(query_results[i])}")
                return False
        return True


Asserter = ResponseAssert()
